import os
import shutil
import uuid
import threading

import ansible_runner
from git import Repo
from django.conf import settings
from .models import Task, TaskState


class AnsibleRunner:
    _semaphore = threading.Semaphore(settings.IAC_EXECUTE_CONCURRENCY)

    def __init__(self, task: Task):
        self.task = task
        self.repository = task.repository
        self.uid = uuid.uuid4().hex
        self.workspace = settings.IAC_WORKSPACE.joinpath(self.uid)

    def prepare(self):
        os.makedirs(self.workspace)
        repo = Repo.clone_from(self.repository.git_url, self.workspace)
        self.task.commit_id = repo.head.commit.hexsha

    def cleanup(self):
        shutil.rmtree(self.workspace)

    def _execute(self):
        with self._semaphore:
            self.prepare()
            self.task.state = TaskState.RUNNING
            self.task.save()
            r = ansible_runner.run(
                private_data_dir=self.workspace,
                playbook=self.task.playbook
            )
            if r.status == 'successful':
                self.task.state = TaskState.COMPLETED
            if r.status == 'failed':
                self.task.state = TaskState.FAILED
            self.task.output = r.stdout.read()
            self.task.save()
            self.cleanup()

    def execute(self):
        threading.Thread(target=self._execute, daemon=True).start()
